package com.youlai.boot.system.service.impl;

import com.itextpdf.text.Document;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.youlai.boot.system.mapper.ExportMapper;
import com.youlai.boot.system.model.entity.TaskTable;
import com.youlai.boot.system.service.ExportService;;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * 实现导出服务的业务层
 */
@Service
public class ExportServiceImpl implements ExportService {

    @Autowired
    private ExportMapper exportMapper; // 注入数据访问层

    /**
     * 导出文档
     * @param format 文档格式
     * @return 文档字节
     */
    @Override
    public ResponseEntity<byte[]> exportDocument(String format) {
        try {
            byte[] documentBytes; // 存储生成的文档字节
            String contentType; // 存储内容类型

            // 根据格式调用相应的方法生成文档
            if ("pdf".equalsIgnoreCase(format)) {
                documentBytes = createPdf(); // 生成PDF文档
                contentType = "application/pdf"; // 设置内容类型为PDF
            } else if ("word".equalsIgnoreCase(format)) {
                documentBytes = createWord(); // 生成Word文档
                contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; // 设置内容类型为Word
            } else {
                return ResponseEntity.badRequest().body(null); // 格式不支持，返回400错误
            }

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=document." + format); // 设置下载文件的名称
            return new ResponseEntity<>(documentBytes, headers, HttpStatus.OK); // 返回生成的文档
        } catch (IOException | DocumentException e) {
            e.printStackTrace(); // 打印异常信息
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); // 返回500错误
        }
    }

    /**
     * 生成PDF文档
     * @return 生成的PDF文档的字节数组
     * @throws IOException IO异常
     * @throws DocumentException 文档异常
     */
    private byte[] createPdf() throws IOException, DocumentException {
        Document document = new Document(); // 创建PDF文档对象
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 创建输出流
        PdfWriter.getInstance(document, outputStream); // 实例化PDF写入器
        document.open(); // 打开文档

        // 使用系统自带的字体
        BaseFont baseFont = BaseFont.createFont("C:/Windows/Fonts/simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); // 创建字体
        Font font = new Font(baseFont); // 创建Font对象

        PdfPTable table = new PdfPTable(5); // 创建5列的表格
        table.setWidthPercentage(100); // 设置表格宽度为100%

        // 添加表头
        addHeaderCellToTable(table, "ID", font);
            addHeaderCellToTable(table, "任务名称", font);
            addHeaderCellToTable(table, "任务负责人", font);
            addHeaderCellToTable(table, "任务创建时间", font);
            addHeaderCellToTable(table, "任务优先级", font);
            addHeaderCellToTable(table, "任务预计开始时间", font);
            addHeaderCellToTable(table, "任务预计结束时间", font);
            addHeaderCellToTable(table, "任务实际开始时间", font);
            addHeaderCellToTable(table, "任务实际结束时间", font);
            addHeaderCellToTable(table, "剩余时间", font);
            addHeaderCellToTable(table, "耗时", font);
            addHeaderCellToTable(table, "任务状态", font);

        int offset = 0; // 数据偏移量
        int batchSize = 1; // 每次获取的数据量
        List<TaskTable> batchData; // 存储用户数据
        int rowIndex = 1; // 行索引

        do {
            batchData = exportMapper.getDataPaging(offset, batchSize); // 分页获取用户数据
            for (TaskTable data : batchData) {
                addDataRowToTable(table, data, font, rowIndex); // 添加数据行到表格
                rowIndex++; // 增加行索引
            }
            offset += batchSize; // 更新偏移量
        } while (!batchData.isEmpty()); // 直到没有更多数据

        document.add(table); // 将表格添加到文档
        document.close(); // 关闭文档
        return outputStream.toByteArray(); // 返回文档字节数组
    }

    /**
     * 添加数据行到表格
     * @param table 表格
     * @param data 数据
     * @param font 字体
     * @param rowIndex 行索引
     */
    private void addDataRowToTable(PdfPTable table, TaskTable data, Font font, int rowIndex) {
        boolean isGray = rowIndex % 2 != 0; // 判断当前行是否为奇数行，用于设置背景色
        addCellToTable(table, String.valueOf(data.getId()), font, isGray);
        addCellToTable(table, data.getTaskname(), font, isGray);
        addCellToTable(table, data.getTaskcharge(), font, isGray);
        addCellToTable(table, String.valueOf(data.getAddtime()), font, isGray);
        addCellToTable(table, data.getTaskpriority(), font, isGray);
        addCellToTable(table, String.valueOf(data.getPredictstart()), font, isGray);
        addCellToTable(table, String.valueOf(data.getPredictcompletion()), font, isGray);
        addCellToTable(table, String.valueOf(data.getCommencement()), font, isGray);
        addCellToTable(table, String.valueOf(data.getClosure()), font, isGray);
        addCellToTable(table, String.valueOf(data.getShengyu()), font, isGray);
        addCellToTable(table, String.valueOf(data.getElapsed()), font, isGray);
        addCellToTable(table, String.valueOf(data.getState()), font, isGray);

    }

    /**
     * 添加单元格到表格
     * @param table 表格
     * @param content 单元格内容
     * @param font 字体
     * @param isGray 是否为灰色背景
     */
    private void addCellToTable(PdfPTable table, String content, Font font, boolean isGray) {
        PdfPCell cell = new PdfPCell(new Phrase(content, font)); // 创建单元格并设置内容和字体
        if (isGray) {
            cell.setBackgroundColor(BaseColor.LIGHT_GRAY); // 设置灰色背景
        }
        cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 设置单元格内容居中
        table.addCell(cell); // 将单元格添加到表格
    }

    /**
     * 添加表头单元格到表格
     * @param table 表格
     * @param content 单元格内容
     * @param font 字体
     */
    private void addHeaderCellToTable(PdfPTable table, String content, Font font) {
        PdfPCell cell = new PdfPCell(new Phrase(content, font)); // 创建表头单元格
        cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 设置表头单元格内容居中
        table.addCell(cell); // 将表头单元格添加到表格
    }

    /**
     * 生成Word文档
     * @return 生成的Word文档的字节数组
     * @throws IOException IO异常
     */
    private byte[] createWord() throws IOException {
        XWPFDocument document = new XWPFDocument(); // 创建Word文档对象
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 创建输出流
        XWPFTable table = document.createTable(); // 创建表格

//        table.setWidth("100%");

        // 设置表格居中
        table.setTableAlignment(TableRowAlign.CENTER);

        // 设置表格边距为0，以确保表格可以在页面中居中
        table.setCellMargins(0, 0, 0, 0);

        // 添加表头
        XWPFTableRow headerRow = table.getRow(0); // 获取表头行
        headerRow.getCell(0).setText("ID");
            headerRow.createCell().setText("任务名称");
            headerRow.createCell().setText("任务负责人");
            headerRow.createCell().setText("任务创建时间");
            headerRow.createCell().setText("任务优先级");
            headerRow.createCell().setText("任务预计开始时间");
            headerRow.createCell().setText("任务预计结束时间");
            headerRow.createCell().setText("任务实际结束时间");
            headerRow.createCell().setText("任务实际结束时间");
            headerRow.createCell().setText("剩余时间");
            headerRow.createCell().setText("耗时");
            headerRow.createCell().setText("任务状态");

        // 设置表头单元格的对齐方式
        for (int i = 0; i < 5; i++) {
            headerRow.getCell(i).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); // 设置垂直居中
        }

        int offset = 0; // 数据偏移量
        int batchSize = 1; // 每次获取的数据量
        List<TaskTable> batchData; // 存储用户数据
        int rowIndex = 1; // 从 1 开始，因为第 0 行是表头

        do {
            batchData = exportMapper.getDataPaging(offset, batchSize); // 分页获取用户数据
            for (TaskTable data : batchData) {
                XWPFTableRow row = table.createRow(); // 创建新行
                row.getCell(0).setText(String.valueOf(data.getId())); // 填充ID
                row.getCell(1).setText(data.getTaskname()); // 填充用户名
                row.getCell(2).setText(data.getTaskpriority()); // 填充密码
                row.getCell(3).setText(String.valueOf(data.getAddtime())); // 填充手机号
                row.getCell(4).setText(data.getTaskcharge()); // 填充密码
                row.getCell(3).setText(String.valueOf(data.getPredictstart())); // 填充手机号
                row.getCell(3).setText(String.valueOf(data.getPredictcompletion())); // 填充手机号
                row.getCell(3).setText(String.valueOf(data.getCommencement())); // 填充手机号
                row.getCell(3).setText(String.valueOf(data.getClosure())); // 填充手机号
                row.getCell(3).setText(String.valueOf(data.getShengyu())); // 填充手机号
                row.getCell(3).setText(String.valueOf(data.getElapsed())); // 填充手机号


                row.getCell(5).setText(String.valueOf(data.getState())); // 填充年龄


                // 设置背景颜色
                if (rowIndex % 2 != 0) { // 判断当前行是否为奇数行
                    // 奇数行，设置背景为灰色
                    for (int i = 0; i < 5; i++) {
                        row.getCell(i).setColor("D9D9D9"); // 设置为浅灰色
                    }
                }
                rowIndex++; // 增加行索引
            }
            offset += batchSize; // 更新偏移量
        } while (!batchData.isEmpty()); // 直到没有更多数据

        // 设置段落的对齐方式为居中
        for (XWPFTableRow row : table.getRows()) { // 遍历所有行
            for (XWPFTableCell cell : row.getTableCells()) { // 遍历每个单元格
                cell.setParagraph(cell.getParagraphs().get(0)); // 确保获取第一个段落
                cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER); // 设置段落居中对齐
            }
        }

        // 写入输出流
        document.write(outputStream); // 将文档写入输出流
        document.close(); // 关闭文档
        return outputStream.toByteArray(); // 返回字节数组
    }
}